package org.pfc.porlapatilla.services;

import java.util.ArrayList;
import java.util.List;

import org.pfc.porlapatilla.DTO.MessageDTO;
import org.pfc.porlapatilla.model.Message;
import org.pfc.porlapatilla.model.User;
import org.pfc.porlapatilla.repositories.AdvancedRepository;
import org.pfc.porlapatilla.repositories.MessageRepository;
import org.pfc.porlapatilla.repositories.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

/**
 * This service provides data management to MessageController.
 * 
 * @author jorgepolobermudez
 * 
 */
@Service
public class MessageService {

    @SuppressWarnings("unused")
    private static final Logger logger = LoggerFactory
	    .getLogger(MessageService.class);

    /**
     * The MessageRepository instance.
     */
    @Autowired
    private MessageRepository messageRepository;
    
    /**
     * The AdvancedRepository instance.
     */
    @SuppressWarnings("unused")
    @Autowired
    private AdvancedRepository advancedRepository;
    
    /**
     * The UserRepository instance.
     */
    @Autowired
    private UserRepository userRepository;

    /**
     * Find stored message by id.
     * 
     * @param id
     *            The message id.
     * @return The found message.
     */
    public MessageDTO findById(String id) {
	return messageRepository.findById(id).toDTO();
    }

    /**
     * Find all stored messages.
     * 
     * @return The list of messages.
     */
    public List<Message> findAll() {
	return (List<Message>) messageRepository.findAll();
    }

    /**
     * Find all stored messages.
     * 
     * @param page
     *            Page number.
     * @param size
     *            Size of page.
     * @return The list of <strong>size</strong> messages in the page
     *         <strong>page</strong>.
     */
    public List<Message> findAll(int page, int size) {
	Page<Message> messages = messageRepository.findAll(new PageRequest(
		page, size));
	return messages.getContent();
    }

    /**
     * Find all messagesDTO sent to <strong>receiver</strong>.
     * 
     * @param receiverId
     *            Message receiver id.
     * @return The list of messagesDTO sent to <strong>receiver</strong>.
     */
    public List<MessageDTO> findByReceiver(String receiverId) {
	List<Message> messages = messageRepository.findByReceiverId(receiverId,
		new Sort(Sort.Direction.DESC, "date"));
	ArrayList<MessageDTO> messageDTOs = new ArrayList<MessageDTO>(
		messages.size());
	for (Message message : messages) {
	    messageDTOs.add(message.toDTO());
	}
	return messageDTOs;
    }

    /**
     * Find all messagesDTO sent to <strong>receiver</strong>.
     * 
     * @param receiverId
     *            Message receiver id.
     * @param page
     *            Page number.
     * @param size
     *            Size of page.
     * @return The List of <strong>size</strong> messagesDTO sent to
     *         <strong>receiver</strong> in the page <strong>page</strong>.
     */
    public List<MessageDTO> findByReceiver(String receiverId, int page, int size) {
	Page<Message> messages = messageRepository.findByReceiverId(receiverId,
		new PageRequest(page, size, Sort.Direction.DESC, "date"));
	ArrayList<MessageDTO> messageDTOs = new ArrayList<MessageDTO>(messages
		.getContent().size());
	for (Message message : messages.getContent()) {
	    messageDTOs.add(message.toDTO());
	}
	return messageDTOs;
    }

    /**
     * Find all messagesDTO sent by <strong>sender</strong>.
     * 
     * @param senderId
     *            Message sender id.
     * @return The list of messagesDTO sent by <strong>sender</strong>.
     */
    public List<MessageDTO> findBySender(String senderId) {
	//List<Message> messages = messageRepository.findBySenderId(senderId,
	//	new Sort(Sort.Direction.DESC, "date"));
	List<Message> messages = messageRepository.findBySenderId(senderId,
		new Sort(Sort.Direction.DESC, "date"));
	ArrayList<MessageDTO> messageDTOs = new ArrayList<MessageDTO>(
		messages.size());
	for (Message message : messages) {
	    messageDTOs.add(message.toDTO());
	}
	return messageDTOs;
    }
    

    /**
     * Find all messages sent by <strong>sender</strong>.
     * 
     * @param senderId
     *            Message sender id.
     * @param page
     *            Page number.
     * @param size
     *            Size of page.
     * @return The list of <strong>size</strong> messages sent by
     *         <strong>sender</strong> in the page <strong>page</strong>.
     */
    public List<MessageDTO> findBySender(String senderId, int page, int size) {
	Page<Message> messages = messageRepository.findBySenderId(senderId,
		new PageRequest(page, size, Sort.Direction.DESC, "date"));
	ArrayList<MessageDTO> messageDTOs = new ArrayList<MessageDTO>(messages
		.getContent().size());
	for (Message message : messages.getContent()) {
	    messageDTOs.add(message.toDTO());
	}
	return messageDTOs;
    }

    /**
     * Store a <strong>message</strong>.
     * 
     * @param messageDTO
     *            The <strong>message</strong> to store.
     * @return The stored <strong>message</strong> id.
     */
    public String store(MessageDTO messageDTO) {
	User sender = userRepository.findByNick(messageDTO.getSenderNick());
	User receiver = userRepository.findByNick(messageDTO.getReceiverNick());
	
	if (sender == null || receiver == null) {
	    return null;
	}
	
	Message message = new Message();
	message.setId(messageDTO.getMessageId());
	message.setDate(messageDTO.getDate());
	message.setReaded(messageDTO.isReaded());
	message.setReceiver(receiver);
	message.setSender(sender);
	message.setText(messageDTO.getText());
	
	return messageRepository.save(message).getId();
    }
    
    /**
     * Delete a <string>message</strong>
     * @param id The message id
     * @return <code>true</code> if the message has been deleted, <code>false</code> otherwise.
     */
    public boolean delete(String id) {
	Message message = messageRepository.findById(id);
	
	if (message == null) {
	    return false;
	}
	
	messageRepository.delete(message);
	return true;
    }
    
}
